﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Mr.LinqToWeibo
{
    internal class MemberBinaryExpressionFinder
        : ExpressionVisitor
    {
        private Expression rootExpression;
        private ExpressionType type;
        private string memberName;
        private BinaryExpression memberBinaryExpression;

        public MemberBinaryExpressionFinder(Expression rootExpression)
        {
            this.rootExpression = rootExpression;
        }

        public BinaryExpression Find(ExpressionType type, string memberName)
        {
            this.type = type;
            this.memberName = memberName;
            this.Visit(this.rootExpression);
            return this.memberBinaryExpression;
        }

        protected override Expression VisitBinary(BinaryExpression b)
        {
            if (b.NodeType == this.type)
            {
                Expression temp = null;
                if (b.Left.NodeType == ExpressionType.MemberAccess
                    || b.Left.NodeType == ExpressionType.Convert)
                {
                    temp = b.Left;
                }
                else if (b.Right.NodeType == ExpressionType.MemberAccess ||
                    b.Right.NodeType == ExpressionType.Convert)
                {
                    temp = b.Right;
                }

                if (temp != null)
                {
                    MemberExpression inner =
                        temp.NodeType == ExpressionType.Convert
                        ? (MemberExpression)((UnaryExpression)temp).Operand
                        : (MemberExpression)temp;

                    if (inner != null && inner.Member.Name == this.memberName)
                    {
                        this.memberBinaryExpression = b;
                    }
                }
            }

            return base.VisitBinary(b);
        }
    }
}
